﻿using System;
using System.Collections.Generic;
using System.Net;
using SimpleFS.Core;

namespace SimpleFS.Providers.Ftp
{
    public class File : IFile
    {
        protected string url;

        protected string user;

        protected string password;

        public File(string url, string user, string password)
        {
            this.url = url;
            this.user = user;
            this.password = password;
        }

        public FtpWebRequest GetRequest(string command)
        {
            FtpWebRequest request  = (FtpWebRequest)FtpWebRequest.Create(this.url);
            request.Credentials = new NetworkCredential(
                this.user, this.password);
            request.UseBinary = true;
            request.KeepAlive = true;

            return request;
        }

        public FtpWebResponse GetResponse(string command)
        {
            return (FtpWebResponse)this.GetRequest(command).GetResponse();
        }

        #region IFile Members

        public System.IO.Stream Read()
        {
            System.IO.FileStream outputStream 
                = new System.IO.FileStream(
                    Guid.NewGuid().ToString(), System.IO.FileMode.Create);
            FtpWebResponse response 
                = this.GetResponse(WebRequestMethods.Ftp.DownloadFile);

            System.IO.Stream ftpStream = response.GetResponseStream();

            long cl = response.ContentLength;
            int bufferSize = 2048;
            int readCount;
            byte[] buffer = new byte[bufferSize];

            readCount = ftpStream.Read(buffer, 0, bufferSize);
            while (readCount > 0)
            {
                outputStream.Write(buffer, 0, readCount);
                readCount = ftpStream.Read(buffer, 0, bufferSize);
            }

            ftpStream.Close();
            outputStream.Close();
            response.Close();

            return outputStream;
        }

        public void Write(System.IO.Stream stream)
        {
            FtpWebRequest request 
                = this.GetRequest(WebRequestMethods.Ftp.UploadFile);

            // Notify the server about the size of the uploaded file
            request.ContentLength = stream.Length;

            // The buffer size is set to 2kb
            int buffLength = 2048;
            byte[] buff = new byte[buffLength];
            int size;

            try
            {
                // Stream to which the file to be upload is written
                System.IO.Stream uploadStream = request.GetRequestStream();

                // Read from the file stream 2kb at a time
                size = stream.Read(buff, 0, buffLength);

                // Till Stream content ends
                while (size != 0)
                {
                    // Write Content from the file stream to the FTP Upload Stream
                    uploadStream.Write(buff, 0, size);
                    size = stream.Read(buff, 0, buffLength);
                }

                // Close the file stream and the Request Stream
                uploadStream.Close();
                stream.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        #endregion

        #region IFileSystemObject Members

        public string Name
        {
            get { return this.url; }
        }

        public DateTime LastModifiedTime
        {
            get { throw new NotImplementedException(); }
        }

        public Dictionary<string, string> Attributes
        {
            get { throw new NotImplementedException(); }
        }

        public IDirectory ParentDirectory
        {
            get { throw new NotImplementedException(); }
        }

        public void Copy(IFileSystemObject target)
        {
            throw new NotImplementedException();
        }

        public void Move(IFileSystemObject target)
        {
            throw new NotImplementedException();
        }

        public void Delete()
        {
            throw new NotImplementedException();
        }

        public bool Exists()
        {
            bool result = false;

            FtpWebResponse response 
                = this.GetResponse(WebRequestMethods.Ftp.GetFileSize);
            System.IO.Stream stream = response.GetResponseStream();
            result = stream != null;

            response.Close();

            return result;
        }

        public void Rename(string newName)
        {
            throw new NotImplementedException();
        }

        public void Close()
        {

        }

        #endregion
    }
}
